"""
Case Type   : xml类型
Case Name   : gs_basebackup物理备份恢复，查询xml数据无变化
Create At   : 2022/8/29
Owner       : songjing20
Description :
    1.创建表,插入数据
    2.查询表
    3.gs_basebackup备份
    4.stop数据库,使用备份目录启动数据库
    5.查询表中xml类型数据是否显示正常
    6.清理环境
Expect      :
    1.成功
    2.成功
    3.成功
    4.成功
    5.与2结果一致
    6.成功
History     :
"""

import os
import unittest

from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant


class XmlDatatype(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.common = Common()
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.pri_node = Node('PrimaryDbUser')
        self.constant = Constant()
        self.backup_path = os.path.join(macro.DB_BACKUP_PATH, 'Xml_0053_bak')
        self.table = 't_xml_0053'

    def test_xml_datatype(self):
        text = '-----step1:创建表,插入数据;expect:成功-----'
        self.log.info(text)
        sql = f'''drop table if exists {self.table} cascade;
        create table {self.table}(c_int int, c_xml xml)
        partition by range(c_int) (
          partition p1 values less than(100),
          partition p2 values less than(1000),
          partition p3 values less than(maxvalue));
        insert into {self.table} values(50, xml'<value>one</value>');
        insert into {self.table} values(666, xmlelement(
        name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as bar)));
        insert into {self.table} values(2000, 
        xml'<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<ROOT>
    <!-- 整体信息 -->
    <CLUSTER>
        <!-- 数据库名称 -->
        <PARAM name=\\"clusterName\\" value=\\"cluster01\\" />
        <!-- 数据库节点名称(hostname1,2) -->
        <PARAM name=\\"nodeNames\\" value=\\"hostname1\\" />
    </CLUSTER>
</ROOT>');'''
        sql_res = self.pri_sh.execut_db_sql(sql)
        self.log.info(sql_res)
        self.assertIn(self.constant.CREATE_TABLE_SUCCESS, sql_res,
                      f'执行失败:{text}')
        self.assertEqual(sql_res.count(self.constant.INSERT_SUCCESS_MSG), 3,
                         f'执行失败:{text}')

        text = '-----step2:查询表;expect:成功，3条数据-----'
        self.log.info(text)
        select_sql = f"select * from {self.table} order by 1;"
        select_res = self.pri_sh.execut_db_sql(select_sql)
        self.log.info(select_res)
        self.assertIn('''50 | <value>one</value>
   666 | <foo bar="2009-04-09T00:24:37"/>
  2000 | <ROOT>                                                +
       |     <!-- 整体信息 -->                             +
       |     <CLUSTER>                                         +
       |         <!-- 数据库名称 -->                      +
       |         <PARAM name="clusterName" value="cluster01" />+
       |         <!-- 数据库节点名称(hostname1,2) -->   +
       |         <PARAM name="nodeNames" value="hostname1" />  +
       |     </CLUSTER>                                        +
       | </ROOT>
(3 rows)''', select_res, f'执行失败:{text}')

        text = '-----step3:gs_basebackup备份; expect:成功-----'
        self.log.info(text)
        backup_cmd = f"mkdir -p {self.backup_path};" \
                     f"chmod 700 {self.backup_path};" \
                     f"source {macro.DB_ENV_PATH};" \
                     f"gs_basebackup -D {self.backup_path} " \
                     f"-Fp -X stream -p {self.pri_node.db_port} "
        self.log.info(backup_cmd)
        backup_res = self.common.get_sh_result(self.pri_node, backup_cmd)
        self.assertIn(self.constant.gs_basebackup_success_msg, backup_res,
                      f'执行失败:{text}')

        text = '-----step4:stop数据库,使用备份目录启动数据库; expect:成功-----'
        self.log.info(text)
        res = self.pri_sh.stop_db_cluster()
        self.log.info(res)
        self.assertTrue(res, f'执行失败:{text}')
        res = self.pri_sh.start_db_instance(dn_path=self.backup_path)
        self.assertIn(self.constant.RESTART_SUCCESS_MSG, res,
                      f'启动失败:{text}')

        text = '-----step5:查询表数据;expect:与step2结果一致-----'
        self.log.info(text)
        res = self.pri_sh.execut_db_sql(select_sql)
        self.log.info(res)
        self.assertEqual(select_res, res, f'执行失败:{text}')

    def tearDown(self):
        text = '-----step6:清理环境;expect:成功-----'
        self.log.info(text)
        stop_res = self.pri_sh.stop_db_instance(dn_path=self.backup_path)
        cmd = f'rm -rf {self.backup_path};' \
              f'if [ -d {self.backup_path} ]; ' \
              f'then echo "exists"; else echo "not exists"; fi'
        self.log.info(cmd)
        res = self.common.get_sh_result(self.pri_node, cmd)
        restart_res = self.pri_sh.restart_db_cluster()
        self.log.info(restart_res)
        status = self.pri_sh.get_db_cluster_status('status')
        self.log.info(status)
        drop_res = self.pri_sh.execut_db_sql(
            f"drop table if exists {self.table};")
        self.log.info(drop_res)
        self.assertIn(self.constant.GS_CTL_STOP_SUCCESS_MSG, stop_res,
                      f'启动失败:{text}')
        self.assertEqual('not exists', res, f'删除文件失败:{text}')
        self.assertTrue(restart_res and status, f'执行失败:{text}')
        self.assertIn(self.constant.DROP_TABLE_SUCCESS, drop_res,
                      f'删表失败:{text}')
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
